
package com.probiz.estore.common.model.order;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;

import com.probiz.estore.Constants;
import com.probiz.estore.cart.util.ShoppingCartUtil;
import com.probiz.estore.common.helper.ConfigUtil;
import com.probiz.estore.common.model.cart.Shoppingcart;
import com.probiz.estore.common.model.customer.Address;
import com.probiz.estore.common.model.customer.Customer;
import com.probiz.estore.common.model.sales.GiftCertificate;
import com.probiz.estore.common.model.system.AppUser;
import com.probiz.estore.common.model.system.PaymentMethod;
import com.probiz.estore.common.model.system.SelfCollectionCentre;
import com.probiz.estore.common.model.system.ShippingRate;
import com.probiz.estore.common.model.system.Wrap;
import com.probiz.estore.common.service.CheckoutService;
import com.probiz.estore.common.service.GiftCertificateService;
import com.probiz.estore.common.service.PaymentMethodService;
import com.probiz.estore.common.service.PromoService;
import com.probiz.estore.common.util.DateUtil;
import com.probiz.estore.common.util.NumberUtil;
import com.probiz.estore.core.util.I18nUtil;
import com.probiz.estore.customer.service.AddressManager;
import com.probiz.estore.customer.service.CustomerManager;
import com.probiz.estore.exception.CheckoutException;
import com.probiz.estore.order.OrderConstants;
import com.probiz.estore.system.service.ShippingMethodManager;
import com.probiz.estore.webapp.util.RequestContext;

/**
 * 结帐session，对结帐事务进行封装.
 */
public class CheckoutSession implements Serializable {

	/**
	 * 
	 */
	private static final long		serialVersionUID			= -3167305114842163052L;
	/** 下单客户信息 * */
	private String                  customerId                  = "";
	/** 收货人信息 * */
	private String					name						= "";
	private String					email						= "";
	private String					address						= "";
	private String					telephone					= "";
	private String					postalcode;
	private String					regionFullName;
	private String					regionId;

	/** 支付信息 * */
	private String					paymentMethodId;													// 支付方式id
	private String					paymentMethodName;													// 支付方式名称
	private Integer					defaultPaymentMethodId;												//默认的支付方式（对于第一次结账需要）
	private String					paymentType;														// 付款方式，例如现金、刷卡
	private String					selfCollectionCentreId;												// 提货中心id
	private String					selfCollectionCentreName;											// 提货中心名称
	private String					exceptedSelfCollectDate;											// 提货时间
	private String					shippingRateId;													    // 运输费率id  页面使用
	private String					shippingMethodId;													// 配送方式id 
	private String					shippingMethodName          ="";									// 配送方式名称
	private String					estimatedDeliveryTime;												// 预计的送货时间（天数）
	private String					specifiedDeliveryTime;												// 客户指定的送货时间
	private String					needConfirmB4Delivery		= Constants.FLAG_FALSE.toString(); 		// 送货前是否需要电话确认(need to before the delivery)
	private BigDecimal				shippingCost				= BigDecimal.ZERO;						// 运费

	/** 发票信息 * */
	private String					invoiceTitle;
	private String					hasInvoice;

	/** 备注信息 * */
	private String					remark;

	/** 包装信息 * */
	private String					wrapId;																// 包装id
	private String					wrapName;															// 包装名称
	private String					imageSrc;															// 包装图片路径
	private BigDecimal				giftWrapCost				= BigDecimal.ZERO;					    // 费用
	private String					wrapNote;															// 包装祝语

	/** 礼券支付 * */
	private String					giftCertificateNo;													// 输入的礼券号码
	private Map<String, JSONObject>	usedGiftCertificates		= new HashMap<String, JSONObject>();
	// 已使用的礼券列表, key - 礼券号码, value - 用于页面显示的json对像

	/** 积分支付 * */
	private Integer					shopPointAmount;													// 使用的积分数
	private Integer					availableShopPoints;												// 用户可用积分数

	/** 结算信息 * */
	private BigDecimal				giftCertificatePaidTotal	= BigDecimal.ZERO;						// 礼券支付金额总计
	private BigDecimal				tax							= BigDecimal.ZERO;						// 税

	private Shoppingcart			shoppingcart;														// 购物车
	private boolean					isFirstTimeCheckout			= true;									// 是否第一次结账
	private boolean					isConsigneeInfoEmpty		= true;									// 收货人信息是否为空白
	private boolean					isShippingMethodEmpty		= true;									// 配送方式是否为空白
	private boolean					isSelfCollectionCentreEmpty	= true;									// 自提方式是否为空白
	
	/** 其他 * */
	private String                  errorMsg;   //错误提示
	private BigDecimal              totalMock                 = BigDecimal.ZERO;                       //临时变量 用于编辑订单保存预览
	private BigDecimal              premiumMock               = BigDecimal.ZERO;                       //临时变量 用于编辑订单保存预览

	public CheckoutSession() {
		super();
		RequestContext.getCurrentHttpRequest().getSession().setAttribute(
				"checkoutSession", this);
	}
	
	public CheckoutSession(boolean isNew) {
		super();
	}

	public CheckoutSession(Shoppingcart shoppingcart) {
		super();
		setShoppingcart(shoppingcart);
		RequestContext.getCurrentHttpRequest().getSession().setAttribute(
				"checkoutSession", this);
	}

	// 清空session
	public static void clear() {
		RequestContext.getCurrentHttpRequest().getSession().removeAttribute(
				"checkoutSession");
	}

	// 应用场景：使用会员的默认地址信息来填充页面上的输入框（收货人地址）
	public void setAddress(Address address) {
		if (address == null)
			return;
		if (isShippingRequired()) {
			name = address.getFirstname();
			email = address.getEmail();
			this.address = address.getAddress();
			telephone = address.getTelephone();
			postalcode = address.getZip();
			regionId = address.getRegionId().toString();
			regionFullName = address.getRegionFullName();
		}else{
			name = address.getFirstname();
			email = address.getEmail();
		}
	}

	// 应用场景：使用会员的最近一张订单信息来填充页面上的输入框（例如收货人地址、支付方式、配送方法）
	public void setSalesOrder(SalesOrder salesOrder) {
		isFirstTimeCheckout = false; // 有历史订单传入，说明不是第一次结账
		PaymentMethod paymentMethod = getPaymentMethodService().getPaymentById(
				salesOrder.getPaymentMethodId());
		if (paymentMethod != null) {
			if (1 == paymentMethod.getIscod()
					&& this.isShippingRequired() == false) {
				// 如果这一次购买的全是虚拟商品，但上一次结账所选择的是先货后款方式（例如货到付款或自提）
				// 这种情况需要操作者重新选择合适的支付方式，所以不需要为其预设数据
			} else {
				paymentMethodId = paymentMethod.getPaymentMethodId().toString();
				paymentMethodName = paymentMethod.getPaymentMethodName();
				if(salesOrder.getPaymentType()!=null){
					paymentType = salesOrder.getPaymentType().toString();
				}
			}
		}

		if (salesOrder.getSelfCollectionCentreId() != null) {
			// 自提点,必须满足当前自提点地区正确
			List<SelfCollectionCentre> selfCollectionCentreList = this.getSelfCollectionCentreList();
			for (SelfCollectionCentre selfCollectionCentre : selfCollectionCentreList) {
				if (salesOrder.getSelfCollectionCentreId().equals(selfCollectionCentre.getSelfCollectionCentreId())) {
					isSelfCollectionCentreEmpty = false;
					this.selfCollectionCentreId = salesOrder.getSelfCollectionCentreId().toString();
					break;
				}
			}
		}
		this.selfCollectionCentreName = salesOrder.getSelfCollectionCentreName();
		this.exceptedSelfCollectDate = DateUtil.convertDateToString(new Date(),	"yyyy-MM-dd");

		if (salesOrder.getOrderAddress()!=null) {
			OrderAddress orderAddress = salesOrder.getOrderAddress();
			
			// 设置地址
			if (isShippingRequired() && !salesOrder.isShippingRequired()){
				//特别情况：如果本次是实体地址,但上一次订单是虚拟地址，那么就用客户的默认地址来填充（前面已做）
				//DO NOTHING
			}else{
				name = orderAddress.getFirstname();
				email = orderAddress.getEmail();
				if (isShippingRequired()){
					isConsigneeInfoEmpty = false;
					address = orderAddress.getAddress1();
					telephone = orderAddress.getPhoneNumber();
					postalcode = orderAddress.getPostalcode();
					regionFullName = orderAddress.getRegionFullName();
					if (null != orderAddress.getRegionId()) {
						regionId = orderAddress.getRegionId().toString();
					}
				}
				
			}
				
			//如果本次所购买的商品是需要配送的  读取能送达到当前地址的配送方式列表
			if(isShippingRequired() && (salesOrder.getShippingMethodId()!=null)){
				List<ShippingRate> shippingRateList = getShippingRateList();
				if (shippingRateList != null && shippingRateList.size() > 0) {
					for (ShippingRate shippingRate : shippingRateList) {
						if (salesOrder.getShippingMethodId().equals(shippingRate.getShippingMethodId())) {
							isShippingMethodEmpty = false;
							shippingRateId = shippingRate.getShippingRateId().toString();
							shippingMethodId  = shippingRate.getShippingMethodId().toString();
							shippingMethodName = shippingRate.getShippingMethod().getShippingMethodName();
							estimatedDeliveryTime = shippingRate.getShippingMethod().getDeliveryTime();
							
							if (shippingRate.getShippingMethod().getSupportSpecifyingDeliveryTime() == 1) {
								specifiedDeliveryTime = salesOrder.getDeliveryTime();
								needConfirmB4Delivery = salesOrder.getNeedConfrimB4Delivery().toString();
							}
							break;
						}
					}
				}
			}
		}

		// 发票
		if (isInvoiceEnabled() && salesOrder.getHasInvoice().intValue() == 1) {
			hasInvoice = "true";
			invoiceTitle = salesOrder.getInvoiceTitle();
		} else {
			hasInvoice = "false";
			invoiceTitle = "";
		}

		calculateCost();
	}

	// 取得当前结帐会话对象
	public static CheckoutSession getCurrentSession() {
		CheckoutSession result = (CheckoutSession) RequestContext
				.getCurrentHttpRequest().getSession().getAttribute(
						"checkoutSession");
		if (result == null) {
			Shoppingcart shoppingcart = ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
			result = new CheckoutSession(shoppingcart);
			
		}
		return result;
	}

	// 取得填写在收货人区域的相关数据
	public Map<String, String> getConsigneeData() {
		Map<String, String> result = new HashMap<String, String>();
		result.put("name", name);
		result.put("email", email);
		result.put("address", address);
		result.put("telephone", telephone);
		result.put("postalcode", postalcode);
		result.put("regionId", regionId);
		result.put("regionFullName", regionFullName);
		if (StringUtils.isBlank(name) || StringUtils.isBlank(email) || StringUtils.isBlank(address) || StringUtils.isBlank(regionId)) {
			isConsigneeInfoEmpty = true;
		} else {
			isConsigneeInfoEmpty = false;
		}
		result.put("isEmptyInfo", String.valueOf(isConsigneeInfoEmpty));

		return result;
	}
	
	// 保存下单客户（代客下单）
	public void setCustomerId(JSONObject json) {
		customerId = json.getString("customerId");
	}
	

	// 保存用户填写在收货人区域里的相关数据
	public void setConsigneeData(JSONObject json) {
		name = json.getString("name");
		email = json.getString("email");
		address = json.getString("address");
		telephone = json.getString("telephone");
		postalcode = json.getString("postalcode");
		regionId = json.getString("regionId");
		regionFullName = json.getString("regionFullName");
	}

	// 取得填写在收货人信息区域(对购买非实体商品)的相关数据
	public Map<String, String> getVirtualConsigneeData() {
		Map<String, String> result = new HashMap<String, String>();
		result.put("name", name);
		result.put("email", email);
		
		if (StringUtils.isBlank(name) || StringUtils.isBlank(email)) {
			isConsigneeInfoEmpty = true;
		}else{
			isConsigneeInfoEmpty = false;
		}
		result.put("isEmptyInfo", String.valueOf(isConsigneeInfoEmpty));

		return result;
	}

	public void setVirtualConsigneeData(JSONObject json) {
		name = json.getString("name");
		email = json.getString("email");
	}

	/**
	 * 应用传入地址对象的值到自身
	 * 
	 * @param address
	 */
	public void applyAddress(Address address) {
		name = address.getFirstname();
		email = address.getEmail();
		this.address = address.getAddress();
		telephone = address.getTelephone();
		postalcode = address.getZip();
		regionId = address.getRegionId().toString();
		regionFullName = address.getRegionFullName();
	}

	// 取得填写在支付方式区域的相关数据
	public Map<String, String> getPaymentMethodData() {
		Map<String, String> result = new HashMap<String, String>();
		if(this.getShoppingcart()== null || this.getShoppingcart().getShoppingCartItems().size()==0){
			//如果购物车为空
			result.put("error", "emptyShoppingcartError");
			return result;
		}
		result.put("paymentMethodId", paymentMethodId);
		result.put("paymentMethodName", paymentMethodName);
		result.put("paymentType", paymentType);
		if(StringUtils.isNotBlank(paymentType)){
			result.put("paymentTypeDesc", I18nUtil.getInstance().getMessage("checkout.paymentMethod.paymentType.label"+paymentType));
		}else{
			result.put("paymentTypeDesc", "");
		}
		result.put("selfCollectionCentreId", selfCollectionCentreId);
		result.put("selfCollectionCentreName", selfCollectionCentreName);
		result.put("exceptedSelfCollectDate", exceptedSelfCollectDate);
		result.put("shippingRateId", shippingRateId);
		result.put("shippingMethodId", shippingMethodId);
		result.put("shippingMethodName", shippingMethodName);
		result.put("estimatedDeliveryTime", estimatedDeliveryTime);
		result.put("specifiedDeliveryTime", specifiedDeliveryTime);
		result.put("shippingCost", shippingCost.toString());
		result.put("needConfirmB4Delivery", needConfirmB4Delivery);
		if(StringUtils.isNotBlank(needConfirmB4Delivery)){
			result.put("needConfirmB4DeliveryDesc", I18nUtil.getInstance().getMessage("checkout.paymentMethod.needConfirmB4Delivery."+needConfirmB4Delivery));
		}else{
			result.put("needConfirmB4DeliveryDesc", "");
		}
		result.put("isShippingRequired", String.valueOf(isShippingRequired()));
		result.put("isEmptyInfo", String.valueOf(StringUtils.isBlank(paymentMethodId)));

		return result;
	}

	// 保存用户填写在支付方式区域里的相关数据
	public void setPaymentMethodData(JSONObject json) {
		// 支付方式
		paymentMethodId = json.getString("paymentMethodId");
		try {
			PaymentMethod paymentMethod = getCheckoutService()
					.getPaymentMethodById(Integer.valueOf(paymentMethodId));
			paymentMethodName = paymentMethod.getPaymentMethodName();
			if (paymentMethod.getIscod() == 1) {
				// 货到付款
				this.paymentType = json.getString("paymentType");
			} else {
				this.paymentType = "";
			}

		} catch (Exception e) {
			// do nothing
		}

		// 自提
		selfCollectionCentreId = json.getString("selfCollectionCentreId");
		if (isSelfCollect() && selfCollectionCentreId != null
				&& selfCollectionCentreId.length() > 0) {
			exceptedSelfCollectDate = json.getString("exceptedSelfCollectDate");
			SelfCollectionCentre selfCollectionCentre = getCheckoutService()
					.getSelfCollectionCentreById(Integer.valueOf(selfCollectionCentreId));
			if (selfCollectionCentre != null) {
				selfCollectionCentreName = selfCollectionCentre.getSelfCollectionCentreName();
			} else {
				selfCollectionCentreName = "N/A";
			}
			shippingCost = BigDecimal.ZERO;
		}

		// 非自提
		this.shippingRateId = json.getString("shippingRateId");
		if (!isSelfCollect() && isShippingRequired()
				&& shippingRateId != null && shippingRateId.length() > 0) {
			Integer shippingRateIdInteger;
			try {
				shippingRateIdInteger = Integer.valueOf(shippingRateId);
			} catch (NumberFormatException e) {
				return;
			}
			ShippingRate shippingRate = getCheckoutService()
					.getShippingRateById(shippingRateIdInteger);
			this.shippingMethodId = shippingRate.getShippingMethodId().toString();
			boolean supportSpecifyingDeliveryTime = (shippingRate
					.getShippingMethod().getSupportSpecifyingDeliveryTime() == 1);
			if (supportSpecifyingDeliveryTime) {
				// 如果所选择的配送方式是支持指定时间放货的就
				this.needConfirmB4Delivery = json.getString("needConfirmB4Delivery");
				this.specifiedDeliveryTime = json.getString("specifiedDeliveryTime");
			} else {
				this.needConfirmB4Delivery = Constants.FLAG_FALSE.toString();
				this.specifiedDeliveryTime = "";
			}

			this.shippingMethodName = shippingRate.getShippingMethod().getShippingMethodName();
			this.estimatedDeliveryTime = shippingRate.getShippingMethod().getDeliveryTime();

			// 计算运费
			this.calculateCost();
		}
	}

	public void setPaymentMethodData4MobileFront(JSONObject json){
		this.isShippingMethodEmpty = false;
		// 支付方式
		PaymentMethod paymentMethod = null;
		paymentMethodId = json.getString("paymentMethodId");
		try {
			paymentMethod = getCheckoutService().getPaymentMethodById(Integer.valueOf(paymentMethodId));
			paymentMethodName = paymentMethod.getPaymentMethodName();
			if (paymentMethod.getIscod() == 1) {
				// 货到付款
				this.paymentType = StringUtils.isNotBlank(this.paymentType) ? this.paymentType : "1";
			} else {
				this.paymentType = "";
			}
		} catch (Exception e) {
			// do nothing
		}
		
		// 自提
		if (isSelfCollect()) {
			if(StringUtils.isNotBlank(selfCollectionCentreId)){
				SelfCollectionCentre selfCollectionCentre = getCheckoutService().getSelfCollectionCentreById(Integer.valueOf(selfCollectionCentreId));
				if (selfCollectionCentre != null) {
					selfCollectionCentreName = selfCollectionCentre.getSelfCollectionCentreName();
					exceptedSelfCollectDate = StringUtils.isNotBlank(exceptedSelfCollectDate) ? exceptedSelfCollectDate : DateUtil.convertDateToString(DateUtil.getAddDay(new Date(), 0), "yyyy-MM-dd");
				}
			}else{
				List<SelfCollectionCentre> selfCollectionCentreList = this.getSelfCollectionCentreList();
				if(selfCollectionCentreList != null && selfCollectionCentreList.size() > 0){
					SelfCollectionCentre selfCollectionCentre = selfCollectionCentreList.get(0);
					selfCollectionCentreId = selfCollectionCentre.getSelfCollectionCentreId().toString();
					selfCollectionCentreName = selfCollectionCentre.getSelfCollectionCentreName();
					exceptedSelfCollectDate = DateUtil.convertDateToString(DateUtil.getAddDay(new Date(), 0), "yyyy-MM-dd");
				}
			}
			
			if(StringUtils.isBlank(selfCollectionCentreId)){
				//不存在自提提货点
				isShippingMethodEmpty = true;
				selfCollectionCentreId = null;
				selfCollectionCentreName = "N/A";
				exceptedSelfCollectDate = "";
			}
			
			shippingCost = BigDecimal.ZERO;
		}
			
		// 非自提
		if (!isSelfCollect() && isShippingRequired()) {
			ShippingRate shippingRate = null;
			if (StringUtils.isNotBlank(shippingRateId)) {
				shippingRate = getCheckoutService().getShippingRateById(Integer.valueOf(shippingRateId));
			}
			if (shippingRate == null 
					|| (Constants.FLAG_TRUE.equals(paymentMethod.getIscod()) 
							&& Constants.FLAG_FALSE.equals(shippingRate.getShippingMethod().getIsCod()))) {
				List<ShippingRate> shippingRateList = this.getShippingRateList();
				if(shippingRateList != null && shippingRateList.size() > 0){
					shippingRate = shippingRateList.get(0);
				}
			}
			
			if(shippingRate == null){
				this.isShippingMethodEmpty = true;
				this.shippingRateId = "";
				this.shippingMethodId = "";
				this.shippingMethodName = "";
				this.estimatedDeliveryTime = "";
				this.specifiedDeliveryTime = "";
				this.needConfirmB4Delivery = Constants.FLAG_FALSE.toString();
			}else{
				this.shippingRateId = shippingRate.getShippingRateId().toString();
				this.shippingMethodId = shippingRate.getShippingMethodId().toString();
				boolean supportSpecifyingDeliveryTime = (shippingRate.getShippingMethod().getSupportSpecifyingDeliveryTime() == 1);
				if (supportSpecifyingDeliveryTime) {
					// 如果所选择的配送方式是支持指定时间放货的就
					this.specifiedDeliveryTime = StringUtils.isNotBlank(this.specifiedDeliveryTime) ? specifiedDeliveryTime : I18nUtil.getInstance().getMessage("checkout.paymentMethod.deliveryTime.value1");
					this.needConfirmB4Delivery = StringUtils.isNotBlank(this.needConfirmB4Delivery) ? needConfirmB4Delivery : Constants.FLAG_FALSE.toString();
				} else {
					this.needConfirmB4Delivery = Constants.FLAG_FALSE.toString();
					this.specifiedDeliveryTime = "";
				}
				
				this.shippingMethodName = shippingRate.getShippingMethod().getShippingMethodName();
				this.estimatedDeliveryTime = shippingRate.getShippingMethod().getDeliveryTime();
			}
			
			// 计算运费
			this.calculateCost();
		}
	}
	
	// 取得填写在支付方式区域的相关数据
	public Map<String, String> getShippingMethodData() {
		Map<String, String> result = new HashMap<String, String>();
		if(this.getShoppingcart()== null || this.getShoppingcart().getShoppingCartItems().size()==0){
			//如果购物车为空
			result.put("error", "emptyShoppingcartError");
			return result;
		}
		result.put("paymentMethodId", paymentMethodId);
		result.put("paymentMethodName", paymentMethodName);
		result.put("paymentType", paymentType);
		if(StringUtils.isNotBlank(paymentType)){
			result.put("paymentTypeDesc", I18nUtil.getInstance().getMessage("checkout.paymentMethod.paymentType.label"+paymentType));
		}else{
			result.put("paymentTypeDesc", "");
		}
		result.put("selfCollectionCentreId", selfCollectionCentreId);
		result.put("selfCollectionCentreName", selfCollectionCentreName);
		result.put("exceptedSelfCollectDate", exceptedSelfCollectDate);
		result.put("shippingRateId", shippingRateId);
		result.put("shippingMethodId", shippingMethodId);
		result.put("shippingMethodName", shippingMethodName);
		result.put("estimatedDeliveryTime", estimatedDeliveryTime);
		result.put("specifiedDeliveryTime", specifiedDeliveryTime);
		result.put("shippingCost", shippingCost.toString());
		result.put("needConfirmB4Delivery", needConfirmB4Delivery);
		if(StringUtils.isNotBlank(needConfirmB4Delivery)){
			result.put("needConfirmB4DeliveryDesc", I18nUtil.getInstance().getMessage("checkout.paymentMethod.needConfirmB4Delivery."+needConfirmB4Delivery));
		}else{
			result.put("needConfirmB4DeliveryDesc", "");
		}
		result.put("isShippingRequired", String.valueOf(isShippingRequired()));
		
		if (isSelfCollect()){
			if (StringUtils.isNotBlank(selfCollectionCentreId)) {
				isSelfCollectionCentreEmpty = false;
			} else {
				isSelfCollectionCentreEmpty = true;
			}
			result.put("isEmptyInfo", String.valueOf(isSelfCollectionCentreEmpty));
		} else {
			if (StringUtils.isNotBlank(shippingRateId)) {
				isShippingMethodEmpty = false;
			} else {
				isShippingMethodEmpty = true;
			}
			result.put("isEmptyInfo", String.valueOf(isShippingMethodEmpty));
		}

		return result;
	}
	
	public void setShippingMethodData4MobileFront(JSONObject json){
		// 支付方式
		try {
			PaymentMethod paymentMethod = getCheckoutService().getPaymentMethodById(Integer.valueOf(paymentMethodId));
			paymentMethodName = paymentMethod.getPaymentMethodName();
			if (paymentMethod.getIscod() == 1) {
				// 货到付款
				this.paymentType = json.getString("paymentType");
			} else {
				this.paymentType = "";
			}
		} catch (Exception e) {
			// do nothing
		}

		// 自提
		selfCollectionCentreId = json.getString("selfCollectionCentreId");
		if (isSelfCollect() && selfCollectionCentreId != null
				&& selfCollectionCentreId.length() > 0) {
			exceptedSelfCollectDate = json.getString("exceptedSelfCollectDate");
			SelfCollectionCentre selfCollectionCentre = getCheckoutService()
					.getSelfCollectionCentreById(Integer.valueOf(selfCollectionCentreId));
			if (selfCollectionCentre != null) {
				selfCollectionCentreName = selfCollectionCentre.getSelfCollectionCentreName();
			} else {
				selfCollectionCentreName = "N/A";
			}
			shippingCost = BigDecimal.ZERO;
		}

		// 非自提
		this.shippingRateId = json.getString("shippingRateId");
		if (!isSelfCollect() && isShippingRequired()
				&& shippingRateId != null && shippingRateId.length() > 0) {
			Integer shippingRateIdInteger;
			try {
				shippingRateIdInteger = Integer.valueOf(shippingRateId);
			} catch (NumberFormatException e) {
				return;
			}
			ShippingRate shippingRate = getCheckoutService()
					.getShippingRateById(shippingRateIdInteger);
			this.shippingMethodId = shippingRate.getShippingMethodId().toString();
			boolean supportSpecifyingDeliveryTime = (shippingRate
					.getShippingMethod().getSupportSpecifyingDeliveryTime() == 1);
			if (supportSpecifyingDeliveryTime) {
				// 如果所选择的配送方式是支持指定时间放货的就
				this.needConfirmB4Delivery = json.getString("needConfirmB4Delivery");
				this.specifiedDeliveryTime = json.getString("specifiedDeliveryTime");
			} else {
				this.needConfirmB4Delivery = Constants.FLAG_FALSE.toString();
				this.specifiedDeliveryTime = "";
			}

			this.shippingMethodName = shippingRate.getShippingMethod().getShippingMethodName();
			this.estimatedDeliveryTime = shippingRate.getShippingMethod().getDeliveryTime();

			// 计算运费
			this.calculateCost();
		}
	}

	// 取得填写在发票区域的相关数据
	public Map<String, String> getInvoiceData() {
		Map<String, String> result = new HashMap<String, String>();
		result.put("invoiceTitle", invoiceTitle);
		result.put("hasInvoice", hasInvoice);

		return result;
	}

	// 保存用户填写在发票区域里的相关数据
	public void setInvoiceData(JSONObject json) {
		hasInvoice = json.getString("hasInvoice");
		if (isInvoiceEnabled() && Constants.FLAG_TRUE.toString().equals(hasInvoice)) {
			invoiceTitle = json.getString("invoiceTitle");
			hasInvoice = Constants.FLAG_TRUE.toString();
		} else {
			invoiceTitle = "";
			hasInvoice = Constants.FLAG_FALSE.toString();
		}
	}

	// 取得填写在礼品包装区域的相关数据
	public Map<String, String> getGiftWrapData() {
		Map<String, String> result = new HashMap<String, String>();
		result.put("wrapId", wrapId);
		result.put("wrapName", wrapName);
		result.put("imageSrc", imageSrc);
		result.put("giftWrapCost", giftWrapCost.toString());
		result.put("wrapNote", wrapNote);

		return result;
	}

	// 保存用户填写在礼品包装区域里的相关数据
	public void setGiftWrapData(JSONObject json) {
		wrapId = json.getString("wrapId");
		if (StringUtils.isNotBlank(wrapId)) {
			try {
				Wrap wrap = getCheckoutService().getWrapById(
						Integer.valueOf(wrapId));
				wrapName = wrap.getWrapName();
				giftWrapCost = wrap.getDefaultPrice();
				wrapNote = json.getString("wrapNote");
				imageSrc = wrap.getImageSrc();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			wrapName = "";
			giftWrapCost = new BigDecimal(0);
			wrapNote = "";
			imageSrc = "";
		}
	}

	// 取得填写在备注区域的相关数据
	public Map<String, String> getRemarkData() {
		Map<String, String> result = new HashMap<String, String>();
		result.put("remark", remark);

		return result;
	}

	// 保存用户填写在备注区域里的相关数据
	public void setRemarkData(JSONObject json) {
		remark = json.getString("remark");
	}

	// 取得填写在使用礼券支付区域的相关数据
	public Map getGiftCertificatePaymentData() {
		Map result = new HashMap();
		result.put("giftCertificateNo", giftCertificateNo);
		result.put("giftCertificatePaidTotal", giftCertificatePaidTotal.setScale(2).toString());
		result.put("usedAmount", String.valueOf(usedGiftCertificates.size())); // 已使用的礼券数量
		JSONArray array = new JSONArray();
		array.addAll(usedGiftCertificates.values());
		result.put("giftCertificateList", array);

		return result;
	}

	// 保存用户填写在礼券支付区域里的相关数据，即使用礼券支付
	public void setGiftCertificatePaymentData(JSONObject json) {
		giftCertificateNo = json.getString("giftCertificateNo");

		if (!usedGiftCertificates.containsKey(giftCertificateNo)) {
			try {
				GiftCertificate giftCertificate = getGiftCertificateService()
						.getGiftCertificateByNo(giftCertificateNo);
				if (giftCertificate != null) {
					BigDecimal total = this.getTotal();
					BigDecimal balance = giftCertificate.getRemainedAmt();
					BigDecimal used = (total.compareTo(balance) > 0) ? balance: total;
					giftCertificatePaidTotal = giftCertificatePaidTotal.add(used);

					JSONObject j = new JSONObject();
					j.put("giftCertificateNo", giftCertificateNo);
					j.put("balance", balance.toString());
					j.put("used", used.toString());
					usedGiftCertificates.put(giftCertificateNo, j);
				}
			} catch (NullPointerException e) {
				// do nothing
			}
		}
		this.giftCertificateNo = "";
	}

	public void removeGiftCertificate(String giftCertificateNo) {
		JSONObject j = usedGiftCertificates.get(giftCertificateNo);
		if (j != null) {
			try {
				String used = j.getString("used");
				giftCertificatePaidTotal = giftCertificatePaidTotal.subtract(new BigDecimal(used));
				usedGiftCertificates.remove(giftCertificateNo);
			} catch (NullPointerException e) {
				// do nothing
			}
		}
	}

	// 取得填写在使用积分支付区域的相关数据
	public Map<String, String> getShopPointPaymentData() {
		Map<String, String> result = new HashMap<String, String>();
		result.put("shopPointAmount", (shopPointAmount == null) ? "0" : shopPointAmount.toString());
		result.put("availableShopPoints", availableShopPoints.toString());
		result.put("shopPointPaidTotal", getShopPointPaidTotal().setScale(2).toString());
		result.put("shopPointPaymentLimit", getShopPointPaymentLimit().toString());
		result.put("shopPointUsedLimit", getShopPointUsedLimit().toString());

		return result;
	}

	// 保存用户填写在积分支付区域里的相关数据，即使用积分支付
	public Map<String, String> setShopPointPaymentData(JSONObject json) {
		Map<String, String> result = new HashMap<String, String>();
		try {
			shopPointAmount = Integer.valueOf(json.getString("shopPointAmount"));
		} catch (NumberFormatException e) {
			result.put("error", I18nUtil.getInstance().getMessage("checkout.error.invalidShoppoint"));
			return result;
		}

		if (shopPointAmount != null && shopPointAmount > getShopPointUsedLimit().intValue()) {
			// 如果输入的积分数大于允许值
			result.put("error",	I18nUtil.getInstance().getMessage("checkout.error.exceedAvailableShopPoint",new Object[] { Integer.valueOf(getShopPointUsedLimit().intValue()) }));
			shopPointAmount = getShopPointUsedLimit().intValue();
		}

		if (shopPointAmount != null && shopPointAmount > availableShopPoints) {
			// 如果输入的积分数大于当前用户的可用积分
			result.put("error",
					I18nUtil.getInstance().getMessage("checkout.error.exceedAvailableShopPoint", new Object[] { Integer.valueOf(availableShopPoints) }));
			shopPointAmount = availableShopPoints;
		}

		// 判断用户输入的积分数是否超过订单未支付的金额（因为还有礼券支付所以复杂了很多）
		BigDecimal nonPaidAmount = getProductTotal().add(getCost()).subtract(getDiscountAmount()).subtract(giftCertificatePaidTotal);
		if (nonPaidAmount.intValue() > 0) {
			int shopPointExchangeRate = ConfigUtil.getInstance().getShopPointExchangeRate();
			int exceptedShopPoint = nonPaidAmount.multiply(new BigDecimal(shopPointExchangeRate)).setScale(0, RoundingMode.UP).intValue();
			if (shopPointAmount > exceptedShopPoint) {
				shopPointAmount = exceptedShopPoint;
			}
		}

		return result;
	}

	// 计算使用积分支付的金额
	private BigDecimal getShopPointPaidTotal() {
		if (shopPointAmount == null) {
			return BigDecimal.ZERO;
		}

		int shopPointExchangeRate = ConfigUtil.getInstance().getShopPointExchangeRate();
		BigDecimal result = new BigDecimal(shopPointAmount).divide(new BigDecimal(shopPointExchangeRate));
		BigDecimal shopPointPaymentLimit = getShopPointPaymentLimit();
		if (result.compareTo(shopPointPaymentLimit) == 1) {
			result = shopPointPaymentLimit; // 不能超过积分支付的最大额度
		}

		return result;
	}

	// 计算积分支付金额上限
	private BigDecimal getShopPointPaymentLimit() {
		int shopPointPaymentLimitPercentage = ConfigUtil.getInstance().getShopPointPaymentLimitPercentage();
		BigDecimal limit = getProductTotal().add(getCost()).subtract(getDiscountAmount()).subtract(giftCertificatePaidTotal)
				.multiply(new BigDecimal(shopPointPaymentLimitPercentage)).divide(new BigDecimal(100)).setScale(2, RoundingMode.UP);
		return limit;
	}

	// 计算可使用积分数上限
	private BigDecimal getShopPointUsedLimit() {
		int shopPointExchangeRate = ConfigUtil.getInstance().getShopPointExchangeRate();
		BigDecimal usedLimit = getShopPointPaymentLimit().multiply(new BigDecimal(shopPointExchangeRate));
		return new BigDecimal(Math.ceil(usedLimit.doubleValue())); // 对积分向上取整，例如18.10积分取整后为19
	}

	public Map<String, String> getBillData() {
		Map<String, String> result = new HashMap<String, String>();
		result.put("total", getTotal().toString());
		result.put("productTotal", getProductTotal().setScale(2).toString());
		result.put("giftWrapCost", giftWrapCost.setScale(2).toString());
		result.put("shippingCost", shippingCost.setScale(2).toString());
		result.put("tax", tax.setScale(2).toString());
		result.put("discount", getDiscountAmount().setScale(2).toString());
		result.put("giftCertificatePaidTotal", giftCertificatePaidTotal.setScale(2).toString());
		result.put("shopPointPaidTotal", getShopPointPaidTotal().setScale(2).toString());

		return result;
	}
	
	/**
	 * 前台使用，使用了￥和逗号进行了分割。
	 * @return
	 */
	public Map<String, String> getBillData4Preview() {
		Map<String, String> result = new HashMap<String, String>();
		result.put("total", NumberUtil.format2String(this.getTotal()));
		result.put("productTotal", NumberUtil.format2String(this.getProductTotal()));
		result.put("giftWrapCost", NumberUtil.format2String(this.giftWrapCost));
		result.put("shippingCost", NumberUtil.format2String(this.shippingCost));
		result.put("tax", NumberUtil.format2String(this.tax));
		result.put("discount", NumberUtil.format2String(this.getDiscountAmount()));
		result.put("giftCertificatePaidTotal", NumberUtil.format2String(this.giftCertificatePaidTotal));
		result.put("shopPointPaidTotal", NumberUtil.format2String(this.getShopPointPaidTotal()));

		return result;
	}

	// 计算订单商品总金额
	public BigDecimal getProductTotal() {
		BigDecimal result = BigDecimal.ZERO;
		if (shoppingcart != null) {
			result = shoppingcart.getSubtotal();
		}
		return result;
	}

	// 计算订单折扣金额
	public BigDecimal getDiscountAmount() {
		BigDecimal result = BigDecimal.ZERO;
		if (shoppingcart != null) {
			result = shoppingcart.getCartDiscountAmount();
		}
		return result;
	}

	// 计算费用
	public BigDecimal getCost() {
		BigDecimal result = BigDecimal.ZERO;
		result = result.add(shippingCost).add(giftWrapCost).add(tax);
		return result;
	}

	// 计算应付金额
	public BigDecimal getTotal() {
		BigDecimal result = BigDecimal.ZERO;
		result = result.add(getProductTotal()).add(getCost()).subtract(
				getDiscountAmount()).subtract(getPaidTotal());

		return result;
	}

	// 计算已支付金额
	public BigDecimal getPaidTotal() {
		BigDecimal result = BigDecimal.ZERO;
		result = result.add(giftCertificatePaidTotal).add(getShopPointPaidTotal());
		return result;
	}

	// 取得能运送到收货人所在地址的所有配送方式（根据所购买的商品计算运费）
	public List<ShippingRate> getShippingRateList() {
		boolean isCod = false;
		PaymentMethod paymentMethod = null;
		if (StringUtils.isNotBlank(this.paymentMethodId)) {
			paymentMethod = getPaymentMethodService().getPaymentById(Integer.valueOf(this.paymentMethodId));
		}else if(null != this.defaultPaymentMethodId){
			paymentMethod = getPaymentMethodService().getPaymentById(this.defaultPaymentMethodId);
		}
		if (paymentMethod != null) {
			isCod = paymentMethod.getIscod() == 1;
		}

		// 取得满足当前所选地区的配送方式
		List<ShippingRate> shippingRateList = getCheckoutService()
				.getRegionShippingRates(isCod,
						Integer.valueOf(this.getRegionId()));

		// 根据当前购买商品的重量，计算每种配送方式实际的运费
		BigDecimal weight = shoppingcart.getWeight();
		for (ShippingRate shippingRate : shippingRateList) {
			BigDecimal projectedShippingCost = getCheckoutService()
					.getShippingExpence(shippingRate.getShippingRateId(),
							weight);
			projectedShippingCost = getPromoService().getShippingFee(
					shoppingcart.getShippingDiscountInfo(),
					shippingRate.getShippingMethod().getShippingMethodId(),
					projectedShippingCost);

			shippingRate.getShippingMethod().setShippingCost(
					projectedShippingCost);
		}

		return shippingRateList;
	}

	// 取得客户所在地区的提货中心列表数据
	public List<SelfCollectionCentre> getSelfCollectionCentreList() {
		List<SelfCollectionCentre> selfCollectionCentreList = getCheckoutService()
				.getSelfCollectionCentreListByRegionId(
						Integer.valueOf(this.getRegionId()));
		return selfCollectionCentreList;
	}

	// 根据当前的结帐信息生成一个订单地址对像
	public Address generateAddress() {
		Address address = new Address();

		address.setAddress(this.address);
		address.setAddress2("");
		address.setRegionId(Integer.valueOf(this.regionId));
		address.setRegionFullName(this.regionFullName);
		address.setEmail(this.email);
		address.setZip(this.postalcode);
		address.setFirstname(this.name);
		address.setLastname("");
		address.setTelephone(this.telephone);
		address.setTitle("");

		return address;
	}

	// 根据当前结账信息生成一个订单对像
	public SalesOrder generateSalesOrder() {
		SalesOrder salesOrder = new SalesOrder();

		
		// ---------------购买客户---------------
		if(RequestContext.isFront()){
			AppUser appUser = RequestContext.getCurrentUser();
			if(null != appUser){
				//由于前台用户可能修改了个人信息，所以重新拿一次
				Customer customer = getCustomerManager().getByAppUserId(appUser.getAppuserId());
				salesOrder.setCustomerId(customer.getAppuserId());
				salesOrder.setCustomerUsername(customer.getAppUserName());
				salesOrder.setCustomerFirstname(customer.getFirstname());
				salesOrder.setCustomerEmail(customer.getEmail());
			}else{
				//前台匿名下单 不需设置customerId
				//DO NOTHING
			}
		}else{
			if(StringUtils.isNotBlank(this.customerId)){
				Customer customer = getCustomerManager().getByAppUserId(Integer.valueOf(this.customerId));
				salesOrder.setCustomerId(customer.getAppuserId());
				salesOrder.setCustomerUsername(customer.getAppUserName());
				salesOrder.setCustomerFirstname(customer.getFirstname());
				salesOrder.setCustomerEmail(customer.getEmail());
			}else{
				//后台匿名下单 不需设置customerId
				//DO NOTHING
			}
		}
		salesOrder.setRemark(this.remark);
		
		// ---------------发票---------------
		if (Constants.FLAG_TRUE.toString().equals(hasInvoice)) {
			salesOrder.setHasInvoice(Constants.FLAG_TRUE);
			salesOrder.setInvoiceTitle(this.invoiceTitle);
		} else {
			salesOrder.setHasInvoice(Constants.FLAG_FALSE);
			salesOrder.setInvoiceTitle(null);
		}
		
		// ---------------包装---------------
		if(StringUtils.isNotBlank(this.wrapId)){
			Wrap wrap = getCheckoutService().getWrapById(
					Integer.valueOf(this.wrapId));
			salesOrder.setWrapId(wrap.getWrapId());
			salesOrder.setWrapName(wrap.getWrapName());
			salesOrder.setWrapNote(this.wrapNote);
		}	
		
		
		// ---------------结算金额---------------
		//注意：this.getTotal 是checkout时候的应付的金额，并不是订单的总额
		salesOrder.setTotalAmount(this.getTotal().add(getPaidTotal()));
		salesOrder.setPaidAmount(this.getPaidTotal());
		salesOrder.setProductCost(this.getProductTotal());
		salesOrder.setWrapCost(this.giftWrapCost);
		salesOrder.setShippingCost(this.shippingCost);
		salesOrder.setTax(this.tax);
		salesOrder.setDiscount(this.getDiscountAmount());
		salesOrder.setPremium(BigDecimal.ZERO);
		salesOrder.setGiftCertificatePaid(this.giftCertificatePaidTotal);
		salesOrder.setPointPaid(this.getShopPointPaidTotal());
		
		salesOrder.setUsedShopPoint(this.shopPointAmount!=null?this.shopPointAmount:Integer.valueOf(0));
		salesOrder.setGainedPoint(this.shoppingcart.getGainedPoint());
		salesOrder.setGainedCouponTypeId(shoppingcart.getGainedCouponTypeId());

		// ---------------支付---------------
		PaymentMethod paymentMethod = getPaymentMethodService().getPaymentById(
				Integer.valueOf(this.paymentMethodId));
		salesOrder.setIsCod(paymentMethod.getIscod());
		salesOrder.setPaymentMethodId(paymentMethod.getPaymentMethodId());
		String paymentTypeName = "";
		if(StringUtils.isNotBlank(paymentType)){
			salesOrder.setPaymentType(Short.valueOf(this.paymentType));
			paymentTypeName = OrderConstants.PAYMENT_TYPE_NAME_ARRAY[Integer.valueOf(this.paymentType)];
		}	
		salesOrder.setPaymentTypeDesc(paymentMethod.getPaymentMethodName()+ " "+ paymentTypeName);

		// ---------------配送 送货地址---------------
		OrderAddress orderAddress = new OrderAddress();
		orderAddress.applyAddress(this.generateAddress());
		salesOrder.setOrderAddress(orderAddress);
		
		if (isConsigneeReqiured()) {
			
			if (isSelfCollect()) {
				salesOrder.setSelfCollectionCentreId(Integer
						.valueOf(this.selfCollectionCentreId));
				salesOrder
						.setSelfCollectionCentreName(this.selfCollectionCentreName);
				try {
					salesOrder.setExceptedSelfCollectDate(DateUtil
							.convertStringToDate("yyyy-MM-dd",
									this.exceptedSelfCollectDate));
				} catch (ParseException e) {
					// do nothing
				}
				salesOrder.setNeedConfrimB4Delivery(Constants.FLAG_FALSE);
			} else {
				salesOrder.setShippingRateId(Integer.valueOf(this.shippingRateId));
				salesOrder.setShippingMethodId(Integer.valueOf(this.shippingMethodId));
				salesOrder.setNeedConfrimB4Delivery(Short.valueOf(this.needConfirmB4Delivery));
				salesOrder.setDeliveryTime(this.specifiedDeliveryTime);
			}
		}else{
			salesOrder.setNeedConfrimB4Delivery(Constants.FLAG_FALSE);
		}
		if (isSelfCollect()){
			salesOrder.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_SELFCOLLECT+" "+this.regionFullName+","+this.selfCollectionCentreName);
		}else{
			if(salesOrder.isCod()){
				salesOrder.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_COD+" "+this.shippingMethodName);
			}else{
				salesOrder.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_CASH+" "+this.shippingMethodName);
			}
		}
		

		return salesOrder;
	}

	// 根据当前结账信息生成订单支付对像
	public List<OrderPayment> generateOrderPayments() {
		List<OrderPayment> orderPaymentList = new ArrayList<OrderPayment>();

		// 礼券支付
		Iterator<String> iterator = usedGiftCertificates.keySet().iterator();
		while (iterator.hasNext()) {
			String giftCertificateNo = iterator.next();
			JSONObject obj = usedGiftCertificates.get(giftCertificateNo);
			String used = obj.getString("used");
			OrderPayment orderPayment = new OrderPayment();
			orderPayment.setDocumentType(OrderPayment.DOCUMENT_TYPE_PAY);
			orderPayment.setPaymentMethodId(OrderConstants.PAYMENT_METHOD_GC);
			orderPayment.setPaymentTypeDesc(OrderConstants.PAYMENT_METHOD_GC_DESC);
			orderPayment.setPaymentAmount(new BigDecimal(used));
			orderPayment.setGiftCertificateNo(giftCertificateNo);
			orderPaymentList.add(orderPayment);
		}

		// 积分支付
		if (shopPointAmount != null && shopPointAmount.intValue() > 0) {
			OrderPayment orderPayment = new OrderPayment();
			orderPayment.setDocumentType(OrderPayment.DOCUMENT_TYPE_PAY);
			orderPayment.setPaymentMethodId(OrderConstants.PAYMENT_METHOD_POINT);
			orderPayment.setPaymentTypeDesc(OrderConstants.PAYMENT_METHOD_POINT_DESC);
			orderPayment.setUsedShopPoint(shopPointAmount);
			orderPayment.setPaymentAmount(getShopPointPaidTotal());
			orderPaymentList.add(orderPayment);
		}

		return orderPaymentList;
	}


	// 根据当前购买的商品判断是否需要填写收货人信息
	public boolean isConsigneeReqiured() {
		if (shoppingcart.getPhysicalProductItems().size() > 0) {
			// 真正需要配送的商品才需要填写收货人信息
			return true;
		}
		// TODO: 积分兑换的礼品可能也需要填写收货人信息

		return false;
	}

	// 是否需要运输配送
	public boolean isShippingRequired() {
		return isConsigneeReqiured();
	}

	// 是否能开发票
	public boolean isInvoiceEnabled() {

		// 需要进行配送的通商品才可以开发票
		if (shoppingcart.getPhysicalProductItems().size() > 0) {
			// 再由系统配置决定是否支持发票
			return ConfigUtil.getInstance().isInvoiceSupported();
		}

		return false;
	}

	// 是否能选择包装
	public boolean isGiftWrapEnabled() {

		// 真正需要配送的商品才可选择包装
		if (shoppingcart.getPhysicalProductItems().size() > 0) {
			// 再由系统配置决定是否支持包装
			return ConfigUtil.getInstance().getIsSupportWrapExpress();
		}

		return false;
	}

	// 是否可用礼卷支付 购买的物品中没有礼券
	public boolean isGiftCertificatePaymentEnabled() {
		return (shoppingcart.getGiftCertificateItems().size() < 1);
	}

	// 是否可用积分支付
	public boolean isShopPointPaymentEnabled() {
		return ConfigUtil.getInstance().isShopPointPaymentEnabled()
				&& (!isAnonymousUser());
	}

	// 是否应用到了促销优惠策略
	public boolean isPromotionApplied() {
		if (shoppingcart.getShoppingCartPromotions() != null
				&& shoppingcart.getShoppingCartPromotions().size() > 0) {
			// 促销规则
			return true;
		}
		if (shoppingcart.getGainedCouponTypeId() != null
				&& shoppingcart.getGainedCouponTypeId().intValue() > 0) {
			// 送coupon
			return true;
		}
		if (shoppingcart.getGainedPoint() != null
				&& shoppingcart.getGainedPoint().intValue() > 0) {
			// 送积分
			return true;
		}

		return false;
	}

	public String getRegionFullName() {
		return regionFullName;
	}

	public String getRegionId() {
		if(StringUtils.isBlank(regionId)){
			regionId =Constants.REGIONID_CHINA.toString();//默认中国
		}
		return regionId;
	}

	public boolean isFirstTimeCheckout() {
		return isFirstTimeCheckout;
	}

	public boolean isConsigneeInfoEmpty() {
		return isConsigneeInfoEmpty;
	}

	// 是否自提
	public boolean isSelfCollect() {
		if ("5".equalsIgnoreCase(this.paymentMethodId)) {
			return true;
		} else {
			return false;
		}
	}

	// 计算各种费用
	private void calculateCost() {
		// 计算运费
		if (isShippingRequired() && shippingRateId != null
				&& shippingRateId.length() > 0) {
			Integer shippingRateIdInteger = Integer.valueOf(this.shippingRateId);
			ShippingRate shippingRate = getCheckoutService()
					.getShippingRateById(shippingRateIdInteger);
			BigDecimal weight = shoppingcart.getWeight();
			shippingCost = getCheckoutService().getShippingExpence(
					shippingRateIdInteger, weight);
			shippingCost = getPromoService().getShippingFee(
					shoppingcart.getShippingDiscountInfo(),
					shippingRate.getShippingMethod().getShippingMethodId(),
					shippingCost);
		}

		// 计税
		if (regionId != null) {
			try {
				getCheckoutService().caculateTaxes(shoppingcart,
						Integer.valueOf(regionId));
				tax = shoppingcart.getTax();
			} catch (NumberFormatException e) {
				// do nothing
			}
		}
	}

	private CheckoutService getCheckoutService() {
		return (CheckoutService) RequestContext
				.getSpringBeanById("checkoutService");
	}

	private PromoService getPromoService() {
		return (PromoService) RequestContext.getSpringBeanById("promoService");
	}

	private GiftCertificateService getGiftCertificateService() {
		return (GiftCertificateService) RequestContext
				.getSpringBeanById("giftCertificateService");
	}

	private PaymentMethodService getPaymentMethodService() {
		return (PaymentMethodService) RequestContext
				.getSpringBeanById("paymentMethodService");
	}
	
	private ShippingMethodManager getShippingMethodManager() {
		return (ShippingMethodManager) RequestContext
				.getSpringBeanById("shippingMethodManager");
	}
	
	private CustomerManager getCustomerManager(){
		return (CustomerManager) RequestContext
		.getSpringBeanById("customerManager");
	}
	

	private AddressManager getAddressManager(){
		return (AddressManager) RequestContext.getSpringBeanById("addressManager");
	}

	public Shoppingcart getShoppingcart() {
		return shoppingcart;
	}

	public void setShoppingcart(Shoppingcart shoppingcart) {
		this.shoppingcart = shoppingcart;
	}

	public void setAvailableShopPoints(Integer availableShopPoints) {
		this.availableShopPoints = availableShopPoints;
	}

	public boolean isAnonymousUser() {
		if (shoppingcart != null
				&& shoppingcart.getCustomerId() != null
				&& !Constants.USERID_ANONYMOUS.equals(shoppingcart
						.getCustomerId())) {
			return false;
		} else {
			return true;
		}
	}

	public boolean isShippingMethodEmpty() {
		return isShippingMethodEmpty;
	}
	
	public boolean isSelfCollectionCentreEmpty() {
		return isSelfCollectionCentreEmpty;
	}

	public String getPaymentMethodId() {
		return paymentMethodId;
	}

	public boolean isTaxEnabled() {
		return getCheckoutService().isTaxEnabled();
	}
	
	
	public String getErrorMsg() {
		return errorMsg;
	}

	public void setErrorMsg(String errorMsg) {
		this.errorMsg = errorMsg;
	}

	//数据校验，不通过则抛出运行时异常
	public void test() throws CheckoutException{
		if(this.getShoppingcart().getShoppingCartItems().size() == 0){
			//g
		}
		if (this.isShippingRequired()) {
			if (StringUtils.isEmpty(name)) {
				String msg = I18nUtil.getInstance().getMessage("checkout.error.consigneeIsRequired");
				throw new RuntimeException(msg);
			}
			if (StringUtils.isEmpty(address)) {
				String msg = I18nUtil.getInstance().getMessage("checkout.error.addressIsRequired");
				throw new RuntimeException(msg);
			}
			if (StringUtils.isEmpty(regionId)) {
				String msg = I18nUtil.getInstance().getMessage("checkout.error.regionIsRequired");
				throw new RuntimeException(msg);
			}
			if (StringUtils.isEmpty(paymentMethodId)) {
				String msg = I18nUtil.getInstance().getMessage("checkout.error.paymentMethodIsRequired");
				throw new RuntimeException(msg);
			}
			if (StringUtils.isEmpty(shippingRateId) && StringUtils.isEmpty(selfCollectionCentreId)) {
				String msg = I18nUtil.getInstance().getMessage("checkout.error.shippingMethodIsRequired");
				throw new RuntimeException(msg);
			}
			
			//检查此时的运输方式是否可用，因为非第一次下单，可能获取了旧数据
			if(StringUtils.isNotEmpty(shippingRateId)){
				boolean isShippingMethodAvailable = false;
				List<ShippingRate> shippingRateList = getShippingRateList();
				if (shippingRateList != null && shippingRateList.size() > 0) {
					for (ShippingRate shippingRate : shippingRateList) {
						if (shippingRateId.equals(shippingRate.getShippingRateId().toString())) {
							isShippingMethodAvailable = true;
							break;
						}
					}
				}
				if(!isShippingMethodAvailable){
					String msg = I18nUtil.getInstance().getMessage("checkout.error.shippingMethodError");
					throw new CheckoutException(CheckoutException.TYPE_SHIPPINGMETHOD_ERROR,msg);
				}
			}
			//检查此时的自提方式是否可用，因为非第一次下单，可能获取了旧数据
			if(StringUtils.isNotEmpty(selfCollectionCentreId)){
				boolean isSelfCollectionCentreAvailable = false;
				List<SelfCollectionCentre> selfCollectionCentreList = this.getSelfCollectionCentreList();
				for (SelfCollectionCentre selfCollectionCentre : selfCollectionCentreList) {
					if (selfCollectionCentreId.equals(selfCollectionCentre.getSelfCollectionCentreId().toString())) {
						isSelfCollectionCentreAvailable = true;
						break;
					}
				}
				if(!isSelfCollectionCentreAvailable){
					String msg = I18nUtil.getInstance().getMessage("checkout.error.selfCollectionCentreError");
					throw new CheckoutException(CheckoutException.TYPE_SELFCOLLECTION_ERROR,msg);
				}
			}
			
		}
		
		if (NumberUtil.isOverMax(this.getProductTotal())) {
			String msg = I18nUtil.getInstance().getMessage("checkout.error.overMaxValue");
			throw new RuntimeException(msg);
		}
	}
	/**
	 * 检查所有必须的字段，如果是空的则设置为空字符串
	 * @param request
	 */
	public void setDataToEmptyStringForNull(JSONObject jsonObject){
		String[] data =  new String[]{
				"name"			,		//收货人姓名
				"email" 			,		//邮件地址
				"telephone" 		,		//固话号码
				"mobile"			,		//移动电话号码
				"postalcode"		,		//邮编
				"address"			,		//地址
				"regionFullName"	,		//地区全名
				"regionId"		,		//地区id
				"paymentMethodId"			,		//支付方式id
				"paymentMethodName"		,		//支付方式名称
				"paymentType"				,		//付款方式，例如现金、刷卡
				"selfCollectionCentreId"	,		//提货中心id
				"selfCollectionCentreName"  ,		//提货中心名称
				"exceptedSelfCollectDate"	,		//提货时间
				"shippingRateId"		,		    //运输费率id
				"shippingMethodName"		,		//配送方式名称
				"estimatedDeliveryTime"	,		//预计的送货时间
				"specifiedDeliveryTime"	,		//用户指定的送货时间
				"shippingCost"			,		//运费
				"needConfirmB4Delivery"	,		//送货前是否需要电话确认(need to confirm before the delivery)
				"wrapId"			,		//包装id
				"wrapName"		,		//包装名称
				"imageSrc"		,		//包装图片路径
				"giftWrapCost"	,		//费用
				"wrapNote"		,		//包装祝语
				"hasInvoice"		,		//是否开具发票
				"invoiceTitle"			//发票抬头
		};
		for(String key : data){
			if(!jsonObject.containsKey(key)){
				jsonObject.put(key, "");
			}
		}
	}

	public BigDecimal getTotalMock() {
		return totalMock;
	}

	public void setTotalMock(BigDecimal totalMock) {
		this.totalMock = totalMock;
	}

	public BigDecimal getPremiumMock() {
		return premiumMock;
	}

	public void setPremiumMock(BigDecimal premiumMock) {
		this.premiumMock = premiumMock;
	}

	public void setDefaultPaymentMethodId(Integer defaultPaymentMethodId) {
		this.defaultPaymentMethodId = defaultPaymentMethodId;
	}

	public Integer getDefaultPaymentMethodId() {
		return defaultPaymentMethodId;
	}
	
	
	
	
	
	
}
